package jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/*
*  封装
* */

public class BasicDao {

    public static <T> List<T> queryMultiple(String sql, RowMapper<T> mapper, Object... args) {
        List<T> list = new ArrayList<>();
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        try {
            connection = JdbcUtilByDruid.getConnection();
            preparedStatement = connection.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }
            set = preparedStatement.executeQuery();

            while (set.next()) {
                list.add(mapper.mapRow(set));
            }
            return list;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtilByDruid.getClose(set, preparedStatement, connection);
        }
    }

    public static <T> T querySingle(String sql, RowMapper<T> mapper, Object... args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        try {
            connection = JdbcUtilByDruid.getConnection();
            preparedStatement = connection.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }
            set = preparedStatement.executeQuery();

            if (set.next()) {
                return mapper.mapRow(set);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtilByDruid.getClose(set, preparedStatement, connection);
        }
        return null;
    }

    public  int update(String sql, Object... args) {
        int line = 0;
        try {
            Connection connection = JdbcUtilByDruid.getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }

            line = preparedStatement.executeUpdate();
            JdbcUtilByDruid.getClose(null, preparedStatement, connection);
        } catch (java.sql.SQLIntegrityConstraintViolationException e) {
            System.out.println("无法添加重复数据！");
            for (int i = 0; i < args.length; i++) {
                System.out.print(args[i]);
                System.out.print("   ");
            }
            System.out.println("\n");
            System.out.println("该数据已存在！");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        return line;
    }

    public <T> RowMapper<T> createRowMapper(Class<T> clazz) {
        return new RowMapper<T>() {
            @Override
            public T mapRow(ResultSet resultSet) throws SQLException {
                try {
                    T instance = clazz.getDeclaredConstructor().newInstance(); // 创建对象实例
                    // 利用反射将结果集映射到对象属性
                    // 假设属性名和数据库列名一致，
                    for (java.lang.reflect.Field field : clazz.getDeclaredFields()) {
                        field.setAccessible(true);
                        String columnName = field.getName(); // 假设属性名和列名一致
                        Object value = resultSet.getObject(columnName);
                        field.set(instance, value);
                    }
                    return instance;
                } catch (Exception e) {
                    throw new RuntimeException("创建对象失败: " + e.getMessage(), e);
                }
            }
        };

    }

}
